/**
 * ESUI (Enterprise Simple UI)
 * Copyright 2015 Baidu Inc. All rights reserved.
 *
 * @ignore
 * @file 选择控件中所用到的列表形结构，使用Table，增加排序功能和底部链接
 * @author hongfeng(homfen@outlook.com)
 */
define(
    function (require) {
        require('esui/Table');
        require('esui/Panel');
        require('esui/Button');

        var esui = require('esui');
        var lib = require('esui/lib');
        var u = require('underscore');
        var $ = require('jquery');
        var eoo = require('eoo');
        var painters = require('esui/painters');

        var RichSelector = require('ub-ria-ui/selectors/RichSelector');

        /**
         * 控件类
         *
         * @class ui.TableRichSelector
         * @extends ui.RichSelector
         */
        var TableRichSelectorPro = eoo.create(
            RichSelector,
            {

                /**
                 * 控件类型，始终为`"TableRichSelectorPro"`
                 *
                 * @type {string}
                 * @override
                 */
                type: 'TableRichSelectorPro',

                /**
                 * @override
                 */
                styleType: 'RichSelector',

                /**
                 * @override
                 */
                initOptions: function (options) {
                    var properties = {
                        /**
                         * @property {Array} datasource
                         *
                         * 数据源，全集数据
                         */
                        datasource: [],

                        /**
                         * @property {Array} selectedData
                         *
                         * 已选的数据
                         */
                        selectedData: [],

                        /**
                         * @property {Array} fields
                         *
                         * 字段，含义与Table相同，searchScope表示这个字段对搜索关键词是全击中还是部分击中
                         */
                        fields: [],

                        /**
                         * @property {Array} defaultSearchFields
                         *
                         * 默认搜索的字段
                         */
                        defaultSearchFields: [],

                        /**
                         * @property {boolean} hasRowHead
                         *
                         * 是否展示表格属性栏
                         */
                        hasRowHead: true,

                        /**
                         * @property {booleam} hasTarget
                         *
                         * 右侧是否有target
                         */
                        hasTarget: false,

                        /**
                         * @property {Array} footerLinks
                         *
                         * 底部链接
                         */
                        footerLinks: []
                    };

                    u.extend(properties, options);
                    // 存一份datasource做恢复过滤使用
                    this.originDatasource = u.clone(properties.datasource);
                    u.each(
                        properties.fields,
                        function (field) {
                            if (field.isDefaultSearchField) {
                                properties.defaultSearchFields.push(field);
                            }
                        }
                    );
                    this.$super([properties]);
                    this.selectedRowClass = this.helper.getPrefixClass('table-row-selected');
                    this.disabledRowClass = this.helper.getPrefixClass('richselector-row-disabled');
                },

                /**
                 * @override
                 */
                initStructure: function () {
                    this.$super(arguments);
                    $(this.main).addClass(
                        this.helper.getPrefixClass('tablerichselector')
                    );
                    // initFooterLink.call(this);
                },

                /**
                 * 重新渲染视图
                 * 仅当生命周期处于RENDER时，该方法才重新渲染
                 *
                 * @param {Array=} 变更过的属性的集合
                 * @override
                 */
                repaint: painters.createRepaint(
                    RichSelector.prototype.repaint,
                    {
                        name: ['datasource', 'selectedData', 'fields'],
                        paint:
                            function (control, datasource, selectedData, fields) {
                                control.refresh();
                                control.fire('change');
                            }
                    }
                ),

                /**
                 * 更新备选区
                 *
                 * @override
                 */
                refreshContent: function () {
                    var data = this.datasource;
                    if (!data || data.length === 0) {
                        this.addState('empty');
                    }
                    else {
                        this.removeState('empty');
                    }

                    var queryList = this.getQueryList();
                    var table = queryList.getChild('table');
                    if (!table) {
                        table = this.createTable(data);
                        queryList.addChild(table, 'table');
                        table.appendTo(queryList.main);
                    }
                    else {
                        table.setDatasource(data);
                        this.selectItems(this.selectedData, true);
                    }
                },

                createTable: function (data) {
                    var fields = u.clone(this.fields);
                    var helper = this.helper;
                    var cls = [
                        helper.getIconClass(),
                        helper.getPrefixClass('richselector-row-action-icon')
                    ].join(' ');

                    fields.push(
                        {
                            field: 'icon',
                            content: function () {
                                return '<span class="' + cls + '"></span>';
                            },
                            title: '',
                            width: 25,
                            stable: true
                        }
                    );
                    var table = esui.create('Table', {
                        datasource: data,
                        fields: fields,
                        sortable: true
                    });

                    var me = this;
                    table.onsort = function (arg) {
                        var field = arg.field.field;
                        var order = arg.order;
                        var data = me.datasource;
                        data.sort(function (a, b) {
                            return a[field] - b[field];
                        });
                        if (order === 'desc') {
                            data.reverse();
                        }
                        me.datasource = u.clone(data);
                        me.refresh();
                    };

                    var main = $(table.main);
                    var rowClass = this.helper.getPrefixClass('table-row');
                    var rows = main.find('.' + rowClass);
                    var me = this;
                    u.each(
                        rows,
                        function (row, index) {
                            if (data[index].isDisabled) {
                                row.addClass(me.disabledRowClass);
                            }
                        }
                    );

                    if (this.mode === 'delete') {
                        main.attr('mode', 'delete');
                    }
                    if (this.hasTarget) {
                        main.attr('mode', 'target');
                    }

                    return table;
                },

                /**
                 * 获取Table
                 *
                 * @return {Object} Table
                 */
                getTable: function () {
                    var queryList = this.getQueryList();
                    return queryList.getChild('table');
                },

                /**
                 * 点击行为分发器
                 *
                 * @param {Event} e 事件对象
                 * @ignore
                 */
                eventDispatcher: function (e) {
                    var tar = $(e.target);
                    var helper = this.helper;
                    var rowClasses = helper.getPrefixClass('table-row');

                    if (tar.hasClass(rowClasses)) {
                        operateRow.call(this, tar);
                    }
                    else {
                        tar = tar.parents('.' + rowClasses);
                        if (tar.length) {
                            operateRow.call(this, tar);
                        }
                    }
                    this.selectedData = this.getSelectedItems();
                },

                /**
                 * 选择全部
                 * 如果当前处于搜索状态，那么只把搜索结果中未选择的选过去
                 *
                 * @public
                 */
                selectAll: function () {
                    this.selectItems(this.datasource, true);
                    this.fire('add');
                    this.fire('change');
                },

                /**
                 * 批量更新选择状态，
                 * 用于外部调用，因此不触发事件
                 *
                 * @param {Array} items 需要更新的对象集合或id集合
                 * @param {boolean} toBeSelected 要选择还是取消选择
                 * @override
                 */
                selectItems: function (items, toBeSelected) {
                    var me = this;
                    if (this.mode !== 'add') {
                        return;
                    }
                    var ids = u.pluck(items, 'id');
                    var data = this.datasource;
                    var table = this.getTable();
                    var rowClass = this.helper.getPrefixClass('table-row');
                    var rows = $(table.main).find('.' + rowClass);
                    u.each(
                        data,
                        function (item, index) {
                            if (u.contains(ids, item.id) && !item.isDisabled) {
                                $(rows[index]).toggleClass(me.selectedRowClass, toBeSelected);
                            }
                        }
                    );
                    this.selectedData = this.getSelectedItems();
                },

                /**
                 * 删除全部
                 *
                 * @override
                 */
                deleteAll: function () {
                    var items = this.mode === 'delete'
                        ? u.clone(this.datasource)
                        : u.clone(this.originDatasource);
                    this.set('originDatasource', []);
                    this.set('datasource', []);
                    this.fire('delete', {items: items});
                    this.fire('change');
                },

                /**
                 * 搜索含有关键字的结果，默认以name为目标搜索
                 *
                 * 可重写
                 *
                 * @param {Array} filters 过滤参数
                 * @public
                 */
                queryItem: function (filters) {
                    // 查找过滤 [{ keys: ['xxx', 'yyy'], value: 'xxx' }]
                    filters = filters || [];
                    // 判断数据的某个field是命中
                    function checkHitByFilterItem(field, expectValue, data) {
                        var hit = false;
                        // 只有字符串类去空格
                        if (typeof expectValue === 'string') {
                            expectValue = lib.trim(expectValue);
                        }

                        // 部分击中
                        if (field.searchScope === 'partial') {
                            if (data[field.field].indexOf(expectValue) !== -1) {
                                hit = true;
                            }
                        }
                        else if (data[field.field] === expectValue) {
                            hit = true;
                        }
                        return hit;
                    }

                    // 判断行数据是否符合过滤要求
                    function checkRowHit(data, index) {
                        return !u.any(
                            filters,
                            function (filter) {
                                var searchFields = [];
                                // keys未定义，则默认选择通过field指定的并集
                                if (filter.keys === undefined) {
                                    searchFields = this.defaultSearchFields;
                                }
                                else {
                                    searchFields = filter.keys;
                                }
                                return !u.any(
                                    searchFields,
                                    function (searchField) {
                                        // 命中一个就算命中
                                        return checkHitByFilterItem.call(this, searchField, filter.value, data);
                                    }
                                );
                            },
                            this
                        );
                    }

                    this.datasource = u.filter(
                        this.originDatasource,
                        checkRowHit,
                        this
                    );

                    this.addState('queried');
                    this.refreshContent();
                },

                /**
                 * 清空搜索的结果
                 *
                 */
                clearData: function () {
                    // 清空数据
                    this.datasource = u.clone(this.originDatasource);
                },

                /**
                 * add(load)型：或许当前选择状态的数据
                 * delete型：获取全部数据
                 *
                 * @return {Object}
                 * @public
                 */
                getSelectedItems: function () {
                    if (this.mode === 'delete') {
                        return this.datasource;
                    }
                    var data = this.datasource;
                    var selectedData = [];
                    var table = this.getTable();
                    $(table.main).find('.' + this.selectedRowClass).each(function (i, row) {
                        var index = parseInt($(row).data('index'), 10);
                        selectedData.push(data[index]);
                    });
                    return selectedData;
                },

                /**
                 * @override
                 */
                getSelectedItemsFullStructure: function () {
                    return this.getSelectedItems();
                },

                /**
                 * 获取当前状态的显示个数
                 *
                 * @return {number}
                 * @override
                 */
                getCurrentStateItemsCount: function () {
                    return this.datasource.length;
                }
            }
        );

        function actionForAdd(row, item) {
            var eventArgs = {
                item: item,
                status: row.hasClass(this.selectedRowClass) ? 1 : -1
            };

            // 需要增加上一个参数，因为有的时候需要了解当前操作的对象是什么
            this.fire('add', eventArgs);
            this.fire('change');
        }

        /**
         * 下面的方法专属delete型table
         *
         * @param {DOMElement} row 行DOM
         * @param {Object} item 要删除的item
         */
        function actionForDelete(row, item) {
            var index = parseInt(row.data('index'), 10);
            this.datasource.splice(index, 1);
            u.each(
                this.originDatasource,
                function (oitem, i) {
                    if (oitem.id === item.id) {
                        index = i;
                    }
                }
            );
            this.originDatasource.splice(index, 1);
            this.refresh();
            // 外部需要知道什么数据被删除了
            this.fire('delete', {items: [item]});
            this.fire('change');
        }

        function actionForLoad(row, item) {
            // 点击未选中的，执行
            if (row.hasClass(this.selectedRowClass)) {
                this.fire('load', {item: item});
                this.fire('change');
            }
        }

        /**
         * 初始化底部的链接
         */
        function initFooterLink() {
            var footerLinks = this.footerLinks;
            if (footerLinks.length) {
                var me = this;
                var helper = this.helper;
                var width = parseInt(100 / footerLinks.length, 10) + '%';
                var linkPanel = esui.create('Panel', {
                    id: helper.getId('linkPanel'),
                    tagName: 'div'
                });
                $(linkPanel.main).addClass(helper.getPrimaryClassName('linkPanel'));
                u.each(
                    footerLinks,
                    function (link) {
                        var button = esui.create('Button', {content: link.text});
                        $(button.main).css('width', width).on('click', function () {
                            me.fire('footerLinkClick', {link: link});
                        });
                        button.appendTo(linkPanel.main);
                    }
                );
                linkPanel.appendTo(this.main);
                this.addChild(linkPanel, 'linkPanel');
            }
        }

        /**
         * 点击一行时进行操作
         *
         * @param {Object} row 选中的行DOM节点
         */
        function operateRow(row) {
            if (row.hasClass(this.disabledRowClass)) {
                return;
            }

            if (this.mode === 'add') {
                if (row.hasClass(this.selectedRowClass)) {
                    if (this.allowUnselectNode) {
                        row.removeClass(this.selectedRowClass);
                    }
                    else {
                        return;
                    }
                }
                else {
                    if (!this.multi) {
                        var table = this.getChild('table');
                        $(table.main).find('.' + this.selectedRowClass).removeClass(this.selectedRowClass);
                    }
                    row.addClass(this.selectedRowClass);
                }
            }

            var index = parseInt($(row).data('index'), 10);
            var data = this.datasource;
            var item = data[index];
            if (!item) {
                return;
            }

            if (this.mode === 'add') {
                actionForAdd.call(this, row, item);
            }
            else if (this.mode === 'delete') {
                actionForDelete.call(this, row, item);
            }
            else if (this.mode === 'load') {
                actionForLoad.call(this, row, item);
            }
        }

        esui.register(TableRichSelectorPro);
        return TableRichSelectorPro;
    }
);
